/*
 * Título: gestHora. Aplicación web de gestión de horarios para conservatorios.
 * Alumnos:
 * - Javier Pardo Muñoz. I.T. Informática de Gestión
 * - Antonio Prior Cazorla. I.T. Informática de Gestión
 * Director: Dr. José Raúl Romero Salguero.
 *     
 *  Copyright (C) 2013 Javier Pardo Muñoz / Antonio Prior Cazorla
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.

 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package es.uco.gesthora.business;

import es.uco.gesthora.business.algoritmo.Arbol;
import es.uco.gesthora.business.algoritmo.CambioGrupo;
import es.uco.gesthora.business.algoritmo.ErrorGrupo;
import es.uco.gesthora.business.algoritmo.SolicitudGrupo;
import es.uco.gesthora.business.algoritmo.HorarioSolicitud;
import es.uco.gesthora.business.algoritmo.Nodo;
import es.uco.gesthora.business.algoritmo.Solicitud;
import es.uco.gesthora.business.gestorEmail.GestorEmail;
import es.uco.gesthora.business.gestorRutas.GestorRutas;
import es.uco.gesthora.data.DAO.DAOGenerarHorarios;
import es.uco.gesthora.data.DAO.DAOAlumno;
import es.uco.gesthora.data.DAO.DAOGrupo;
import es.uco.gesthora.data.DAO.DAOHorario;
import es.uco.gesthora.data.DAO.DAOSolicitudGrupo;
import java.util.Hashtable;
import java.util.Vector;

/**
 * Maneja la capa de datos de todo lo relacionado con el Algoritmo
 *
 *
 * @author Javier Pardo Muñoz / Antonio Prior Cazorla
 *
 */
public class GenerarHorarios {

    private static GenerarHorarios instance = new GenerarHorarios();
    private DAOGenerarHorarios dGenerarHorarios = null;

    /**
     * Constructor por defecto
     */
    private GenerarHorarios() {
        dGenerarHorarios = DAOGenerarHorarios.getInstance();
    }

    /**
     * Devuelve una instancia de la clase usando el patrón Singleton
     *
     * @return Instancia de la clase DAOAlgoritmo
     */
    public static GenerarHorarios getInstance() {
        return instance;
    }

    /**
     * Se inicia el algoritmo
     */
    public void iniciarAlgoritmo() throws InterruptedException {
        // Declaración de variables
        Arbol arbol = new Arbol();
        DAOSolicitudGrupo dSolicitud = DAOSolicitudGrupo.getInstance();
        DAOGrupo dGrupo = DAOGrupo.getInstance();
        DAOHorario dHorario = DAOHorario.getInstance();
        DAOAlumno dAlumno = DAOAlumno.getInstance();
        Vector<ErrorGrupo> errorGrupo = null;
        Vector<Hashtable> hashAsignatura = new Vector();
        Vector<Hashtable> hashAlumno = new Vector();
        Vector<Hashtable> hashGrupo = new Vector();
        Vector<Hashtable> hashSolicitud = new Vector();
        Vector<Hashtable> vHorario = new Vector();
        Vector<Solicitud> infoSolicitud = new Vector();
        Vector solicitud = new Vector();
        Vector<CambioGrupo> vCambioGrupo = new Vector();
        int solucionados = 0;
        Vector vAux;
        Nodo raiz;
        Nodo mejor = new Nodo();
        int idAlumno;
        int contCambioGrupo = 0;
        int cont;
        int numeroAsignaturas = 0;
        int solicitudesNoValidad = 0;
        dGenerarHorarios.iniciarTablaAlgoritmo();
        //Se inserta el listado de alumnos en la variable hashAlumno
        hashAlumno = (Vector<Hashtable>) dAlumno.seleccionarTodo();
        //recorrer todos los alumnos.
        for (int a = 0; a < hashAlumno.size(); a++) {
            // for (int a = 0; a < 2; a++) {
            idAlumno = Integer.parseInt(hashAlumno.get(a).get("idUsuario").toString());
            //idAlumno = 638;
            System.out.println("Alumno---------> " + idAlumno);
            hashAsignatura = (Vector<Hashtable>) dSolicitud.seleccionarAsignaturaSolicitudPorIdAlumno(idAlumno);

            //contar el numero de Asignaturas e insertarlas en el hashAsignaturas para posteriormente hacer consultas de ellas
            if (!hashAsignatura.isEmpty()) {
                numeroAsignaturas = hashAsignatura.size();
                hashGrupo.removeAllElements();
                //Se buscan los grupos con plaza libre
                for (int i = 0; i < hashAsignatura.size(); i++) {
                    System.out.println(hashAsignatura.get(i).get("idAsignatura"));
                    vAux = dGrupo.seleccionarGrupoPlazaLibre(Integer.parseInt(hashAsignatura.get(i).get("idAsignatura").toString()));

                    //Se añade a hashGrupo los grupos de la asignatura.
                    if (!vAux.isEmpty()) {
                        for (int e = 0; e < vAux.size(); e++) {
                            hashGrupo.addElement((Hashtable) vAux.get(e));
                        }
                    }
                }
                if (!hashGrupo.isEmpty()) {
                    //Se buscan las solicitudes del alumnos actual y se inserta en el hashSolicitud
                    hashSolicitud = (Vector<Hashtable>) dSolicitud.seleccionarPorIdAlumno(idAlumno);
                    infoSolicitud.removeAllElements();
                    //Se comienza la creacion del vector que usaremos como información
                    for (int i = 0; i < hashGrupo.size(); i++) {
                        infoSolicitud.addElement(new Solicitud(Integer.parseInt(hashGrupo.get(i).get("idGrupo").toString()), Integer.parseInt(hashGrupo.get(i).get("idAsignatura").toString())));
                    }
                    for (int i = 0; i < hashSolicitud.size(); i++) {
                        for (int e = 0; e < infoSolicitud.size(); e++) {
                            if (infoSolicitud.get(e).getNumeroGrupo() == hashSolicitud.get(i).get("idGrupo")) {
                                infoSolicitud.get(e).setPrioridad(Integer.parseInt(hashSolicitud.get(i).get("prioridad").toString()));
                            }
                        }
                    }

                    //Se consulta el horario de cada uno de los grupos y se inserta en el vector de información.
                    for (int i = 0; i < infoSolicitud.size(); i++) {
                        vHorario = (Vector<Hashtable>) dHorario.seleccionarHorarios(infoSolicitud.get(i).getNumeroGrupo());
                        infoSolicitud.get(i).setVHashtableHorario(vHorario);
                        vHorario = new Vector();
                    }

                    for (int i = 0; i < infoSolicitud.size(); i++) {
                        System.out.println("NumeroGrupo:" + infoSolicitud.get(i).getNumeroGrupo() + " prioridad: " + infoSolicitud.get(i).getPrioridad() + " Asignatura: " + infoSolicitud.get(i).getIdAsignatura() + "Horario" + infoSolicitud.get(i).vHorarioToString());
                    }

                    //Empieza la creacion del arbol
                    solicitud = new Vector();
                    for (int i = 0; i < infoSolicitud.size(); i++) {
                        solicitud.addElement(0);
                    }
                    raiz = new Nodo(valorarSolicitud(solicitud, numeroAsignaturas, infoSolicitud), solicitud);
                    Vector copiaSolicitudes = new Vector();
                    for (int i = 0; i < solicitud.size(); i++) {
                        copiaSolicitudes.addElement(0);
                    }
                    copiaSolicitudes.set(0, 1);
                    mejor = arbol.rellenarArbol(copiaSolicitudes, 0, null, numeroAsignaturas, sumarSolicitudesMaxPrioridad(idAlumno), infoSolicitud, raiz, raiz);
                    System.out.println("NUMERO DE NODOS DEL ARBOL = " + arbol.contarNodos(raiz) + " y mejor solucion " + mejor.getStringSolicitud());
                    //hay que asignar la solicitud antes de hacer el postproceso y se inserta las solicitude aprobadas en la base de datos.
                    anadirSolicitudAprobada(infoSolicitud, mejor.getSolicitud(), idAlumno);

                }
                //Si el valor del mejor nodo es menor al numero de asignaturas entonces se realizar un post-Algoritmo ya que el algoritmo no ha podido encontrar una solicitud para todas las asignaturas matriculadas
                System.out.println(mejor.getValor() + "  numAsig ->" + numeroAsignaturas);
                if (mejor.getValor() < numeroAsignaturas) {
                    solicitudesNoValidad++;
                    //Busca grupos valido para el cambio de grupo
                    vCambioGrupo = BuscarGrupoValido(infoSolicitud, solicitud, numeroAsignaturas, idAlumno);
                    for (int i = 0; i < vCambioGrupo.size(); i++) {
                        System.out.println(" idAsig: " + vCambioGrupo.get(i).getIdAsignatura() + " idGrupAnt: " + vCambioGrupo.get(i).getGrupoNuevo() + " idGrupNuv: " + vCambioGrupo.get(i).getGrupoAntiguo());
                    }
                    //Realiza el cambio de grupo si fuese posible
                    contCambioGrupo = BuscarCambioGrupo(vCambioGrupo, idAlumno);
                    System.out.println("cont Cambio Grupo " + contCambioGrupo);
                    //Si contCambioGrupo es distinto a la longitud vCambioGrupo, entonces no se ha realizado todo los cambios
                    if (contCambioGrupo != vCambioGrupo.size() || contCambioGrupo == 0) {
                        System.out.println("resalizar el algoritmo");
                        //Busca los grupos erroneos de la solicitudes
                        errorGrupo = BuscarErrores(infoSolicitud, mejor.getSolicitud(), numeroAsignaturas, idAlumno);
                        for (int i = 0; i < errorGrupo.size(); i++) {
                            System.out.println("ERROR en " + errorGrupo.get(i).getNumeroGrupo());
                        }
                        //Comienza el post-Algoritmo para hacer hueco en los errores de grupos
                        System.out.println("Esperando postAlgoritmo...");
                        cont = postAlgoritmo(errorGrupo);
                        //Si cont es igual al numero de errores entonces se ha solucionado los errores
                        if (cont == errorGrupo.size()) {
                            System.out.println(" ERROR SOLUCIONADO ---");
                            eliminarCambioGrupo(idAlumno);
                            restaurarProvisionales();
                            solucionados++;
                        } else {
                            System.out.println(" ERROR NO SE PUDO SOLUCIONAR ***");
                            restaurarAprobadas();
                        }

                    } else {
                        System.out.println("todo ok");
                        aumentarPlazasOcupadas(idAlumno);
                    }
                } else {
                    aumentarPlazasOcupadas(idAlumno);
                    System.out.println("mejor valor -> " + mejor.getValor() + " solicitud ->" + mejor.getStringSolicitud() + " idAlumno " + idAlumno);
                }

            }
            System.out.println("-----------------");
            System.out.println("solicitudes no validad = " + solicitudesNoValidad + " Solucionados " + solucionados);
        }
        dGenerarHorarios.PasarSolicitudAprobadaGruposAlumnos();
        enviarCorreos();
    }

    /**
     * Se encarga de valora la solicitud
     *
     * @param solicitudes: un vector que contiene 1 ò 0 dependiendo de si dicho
     * grupo esta dentro del horario o no
     * @param numeroAsignaturas: numero de Asignaturas en las cuales el alumno
     * se ha matriculado
     * @param infoSolicitudes: vector con toda la información necesaria sobre
     * las solicitudes
     * @return Un entero con el valor de la solicitud
     */
    public int valorarSolicitud(Vector Solicitudes, int numeroAsignaturas, Vector<Solicitud> infoSolicitudes) {
        int valor = 0;
        int contUnos = 0;
        //Se recorre la solicitud
        for (int i = 0; i < Solicitudes.size(); i++) {
            //Se cuenta el numero de unos
            if (Integer.parseInt(Solicitudes.get(i).toString()) == 1) {
                contUnos++;
                //Dependiendo de la prioridad se suma un valor al resultado
                if (infoSolicitudes.get(i).getPrioridad() == 1) {
                    valor += 15;
                } else {
                    if (infoSolicitudes.get(i).getPrioridad() == 2) {
                        valor += 10;
                    } else {
                        if (infoSolicitudes.get(i).getPrioridad() == 3) {
                            valor += 5;
                        } else {
                            valor += 1;
                        }
                    }
                }
            }
        }
        //Si el numero de unos es menor que el numero de Asignaturas, entonces el resultado es igual al numero de unos 
        if (contUnos != numeroAsignaturas) {
            valor = contUnos;

        }
        return valor;
    }

    /**
     * Se encarga de buscar y realizar los cambios de grupos del algoritmo
     *
     * @param vCambioGrupo: un vector con la información de los cambios de
     * grupos
     * @param idAlumno: identificador del alumno con dificultades en el horario
     *
     * @return devuelve el numero de cambios de grupos realizados
     */
    public int BuscarCambioGrupo(Vector<CambioGrupo> vCambioGrupo, int idAlumno) {
        //Declaración de variables
        int resultado = 0;
        Vector v = new Vector();
        //busca alguien que quiera realizar el cambio inverso
        for (int i = 0; i < vCambioGrupo.size(); i++) {
            System.out.println("N: " + vCambioGrupo.get(i).getGrupoNuevo() + " Ant: " + vCambioGrupo.get(i).getGrupoAntiguo() + " id: " + idAlumno);
            v = SeleccionarGrupoNuevo(vCambioGrupo.get(i).getGrupoAntiguo(), vCambioGrupo.get(i).getGrupoNuevo(), idAlumno);
            if (!v.isEmpty()) {
                resultado++;
            }
        }
        //Si resultado es igual a la longitud del vCambioGrupo entonces se realiza todos los cambios
        if (resultado == vCambioGrupo.size()) {
            for (int i = 0; i < vCambioGrupo.size(); i++) {
                System.out.println("SeleccionarGrupo: ");
                v = SeleccionarGrupoNuevo(vCambioGrupo.get(i).getGrupoAntiguo(), vCambioGrupo.get(i).getGrupoNuevo(), idAlumno);
                System.out.println("insertar: ");
                eliminarSolicitudesAprobadas(Integer.parseInt(((Hashtable) v.get(0)).get("idUsuario").toString()), vCambioGrupo.get(i).getGrupoNuevo());
                insertarSolicitud(idAlumno, vCambioGrupo.get(i).getGrupoNuevo());
                insertarSolicitud(Integer.parseInt(((Hashtable) v.get(0)).get("idUsuario").toString()), vCambioGrupo.get(i).getGrupoAntiguo());
                aumentarPlazasOcupadasIdGrupo(vCambioGrupo.get(i).getGrupoAntiguo());
                reducirPlazasOcupadasIdGrupo(vCambioGrupo.get(i).getGrupoNuevo());
                System.out.println("eliminar: ");
                eliminarCambioGrupo(idAlumno, vCambioGrupo.get(i).getGrupoAntiguo(), vCambioGrupo.get(i).getGrupoNuevo());
                eliminarCambioGrupo(Integer.parseInt(((Hashtable) v.get(0)).get("idUsuario").toString()), vCambioGrupo.get(i).getGrupoNuevo(), vCambioGrupo.get(i).getGrupoAntiguo());
            }
        } else {
            for (int i = 0; i < vCambioGrupo.size(); i++) {
                anadirCambioGrupo(idAlumno, vCambioGrupo.get(i).getGrupoAntiguo(), vCambioGrupo.get(i).getGrupoNuevo());
            }
        }
        return resultado;
    }

    /**
     * Se encarga de buscar grupos validos para la solicitud
     *
     * @param infoSolicitudes: un vector con la información necesaria de toda la
     * solicitud
     * @param solicitudes: vector con la solicitud
     * @param numeroAsignaturas: numero de asignaturas
     * @param idAlumno: identificador del alumno con dificultades en el horario
     *
     * @return devuelve un vector<CambioGrupo> con la informaciñon de los grupos
     * para realizar el cambio
     */
    public Vector<CambioGrupo> BuscarGrupoValido(Vector<Solicitud> infoSolicitudes, Vector solicitudes, int numeroAsignaturas, int idAlumno) {
        //Declaración de variables
        Arbol arbol = new Arbol();
        Vector<Hashtable> vError = new Vector();
        Vector<ErrorGrupo> errorGrupo = new Vector();
        Vector<CambioGrupo> cambioGrupo = new Vector();
        Vector<Solicitud> copiaInfoSolicitudes = new Vector();
        Vector copiaSolicitudes = new Vector();
        int idAsigAnt = 0;
        boolean encontrado = false;
        int aux = 0;
        //Se realizan copias de los vectores infoSolicitudes y solicitudes para que posteriormente no se modifiquen
        for (int i = 0; i < infoSolicitudes.size(); i++) {
            copiaInfoSolicitudes.addElement(infoSolicitudes.get(i));
            copiaSolicitudes.addElement(solicitudes.get(i));
        }
        //Busca el grupo de esta solicitud donde tengo plaza ahora mismo
        vError = seleccionarErroresGrupo(idAlumno);
        idAsigAnt = -1;
        for (int i = 0; i < vError.size(); i++) {
            if (Integer.parseInt(vError.get(i).get("idAsignatura").toString()) != idAsigAnt) {
                aux = 0;
                while (aux < copiaInfoSolicitudes.size() && encontrado == false) {
                    System.out.println(vError.get(i).get("idAsignatura") + " " + copiaInfoSolicitudes.get(aux).getIdAsignatura() + "&&" + encontrado);
                    if (Integer.parseInt(vError.get(i).get("idAsignatura").toString()) == copiaInfoSolicitudes.get(aux).getIdAsignatura()) {
                        cambioGrupo.addElement(new CambioGrupo(copiaInfoSolicitudes.get(aux).getIdAsignatura(), copiaInfoSolicitudes.get(aux).getNumeroGrupo()));
                        encontrado = true;
                    }
                    aux++;
                }
            }
            encontrado = false;
            idAsigAnt = Integer.parseInt(vError.get(i).get("idAsignatura").toString());
        }
        //Cuando no este en copiaInfoSolicitud entonces se añade al vector
        for (int i = 0; i < vError.size(); i++) {
            for (int e = 0; e < copiaInfoSolicitudes.size(); e++) {
                if (copiaInfoSolicitudes.get(e).getNumeroGrupo() == Integer.parseInt(vError.get(i).get("idGrupo").toString())) {
                    encontrado = true;
                }
            }
            if (!encontrado) {
                copiaInfoSolicitudes.addElement(new Solicitud(Integer.parseInt(vError.get(i).get("idGrupo").toString()), Integer.parseInt(vError.get(i).get("idAsignatura").toString())));
                copiaSolicitudes.addElement(0);
            }
            encontrado = false;
        }
        //Añade los horarios de los grupos añadidos
        for (int i = 0; i < copiaInfoSolicitudes.size(); i++) {
            if (copiaInfoSolicitudes.get(i).getVHorario().isEmpty()) {
                copiaInfoSolicitudes.get(i).setVHorario(ListarHorario(copiaInfoSolicitudes.get(i).getNumeroGrupo()));
            }
        }
        //Se crea el arbol
        Nodo raiz = new Nodo(valorarSolicitud(copiaSolicitudes, numeroAsignaturas, copiaInfoSolicitudes), copiaSolicitudes);
        Vector copiaSolicitudes2 = new Vector();
        for (int i = 0; i < copiaSolicitudes.size(); i++) {
            copiaSolicitudes2.addElement(copiaSolicitudes.get(i));
        }
        encontrado = false;
        while (aux < copiaSolicitudes2.size() && !encontrado) {
            if (Integer.parseInt(copiaSolicitudes2.get(aux).toString()) == 0 && validarSolicitud(copiaSolicitudes2, aux, copiaInfoSolicitudes)) {
                encontrado = true;
            }
            aux++;
        }
        aux = aux - 1;
        copiaSolicitudes2.set(aux, 1);
        Nodo mejor = arbol.rellenarArbol(copiaSolicitudes2, 0, null, numeroAsignaturas, numeroAsignaturas, copiaInfoSolicitudes, raiz, raiz);
        // algoritmo.anadirSolicitudHueco(infoSolicitudes, mejor.getSolicitud(), idAlumno);
        //Busca el grupo nuevo donde meter al alumno con problemas en el horario
        for (int i = 0; i < mejor.getSolicitud().size(); i++) {
            if (Integer.parseInt(mejor.getSolicitud().get(i).toString()) == 1) {
                for (int e = 0; e < vError.size(); e++) {
                    if (copiaInfoSolicitudes.get(i).getNumeroGrupo() == Integer.parseInt(vError.get(e).get("idGrupo").toString())) {
                        errorGrupo.addElement(new ErrorGrupo(copiaInfoSolicitudes.get(i).getIdAsignatura(), copiaInfoSolicitudes.get(i).getNumeroGrupo(), 1));
                    }
                }
            }
        }
        for (int i = 0; i < errorGrupo.size(); i++) {
            for (int e = 0; e < cambioGrupo.size(); e++) {
                if (errorGrupo.get(i).getIdAsignatura() == cambioGrupo.get(e).getIdAsignatura()) {
                    cambioGrupo.get(e).setGrupoNuevo(errorGrupo.get(i).getNumeroGrupo());
                }
            }
        }
        return cambioGrupo;
    }

    /**
     * Se encarga de buscar grupos no validos para la solicitud actual y
     * devuelve un vector con los grupos donde se tiene que hacer hueco
     *
     * @param infoSolicitudes: un vector con la información necesaria de toda la
     * solicitud
     * @param solicitudes: vector con la solicitud
     * @param numeroAsignaturas: numero de asignaturas
     * @param idAlumno: identificador del alumno con dificultades en el horario
     *
     * @return devuelve un vector<ErrorGrupo> con la información de los grupos a
     * los que se le tiene que hacer hueco
     */
    public Vector<ErrorGrupo> BuscarErrores(Vector<Solicitud> infoSolicitudes, Vector solicitudes, int numeroAsignaturas, int idAlumno) {
        //Declaración de variables
        Arbol arbol = new Arbol();
        Vector<Hashtable> vError = new Vector();
        Vector<ErrorGrupo> errorGrupo = new Vector();
        boolean encontrado = false;
        //Se buscan las asignaturas solicitadas no aprobadas
        vError = seleccionarErroresGrupo(idAlumno);
        //Se busca en el vector infoSolicitudes los grupos de la asignatura no aprobadas, los grupos que no esten en infoSolicitudes se insertan en el vector
        for (int i = 0; i < vError.size(); i++) {
            for (int e = 0; e < infoSolicitudes.size(); e++) {
                if (infoSolicitudes.get(e).getNumeroGrupo() == vError.get(i).get("idGrupo")) {
                    encontrado = true;
                }
            }
            if (!encontrado) {
                infoSolicitudes.addElement(new Solicitud(Integer.parseInt(vError.get(i).get("idGrupo").toString()), Integer.parseInt(vError.get(i).get("idAsignatura").toString())));
                solicitudes.addElement(0);
            }
            encontrado = false;
        }
        //Se buscan los horarios de los grupos nuevos
        for (int i = 0; i < infoSolicitudes.size(); i++) {
            if (infoSolicitudes.get(i).getVHorario().isEmpty()) {
                infoSolicitudes.get(i).setVHorario(ListarHorario(infoSolicitudes.get(i).getNumeroGrupo()));
            }
        }
        //Se genera el arbol
        for (int i = 0; i < solicitudes.size(); i++) {
            solicitudes.set(i, 0);
        }
        Nodo raiz = new Nodo(valorarSolicitud(solicitudes, numeroAsignaturas, infoSolicitudes), solicitudes);
        Vector copiaSolicitudes = new Vector();
        for (int i = 0; i < solicitudes.size(); i++) {
            copiaSolicitudes.addElement(0);
        }
        copiaSolicitudes.set(0, 1);
        Nodo mejor = arbol.rellenarArbol(copiaSolicitudes, 0, null, numeroAsignaturas, numeroAsignaturas, infoSolicitudes, raiz, raiz);
        //Añade la solicitud en la  tabla solicitudHueco
        anadirSolicitudHueco(infoSolicitudes, mejor.getSolicitud(), idAlumno);
        //Inserta el grupo al que se tiene que hacer hueco en el vector errorGrupo.
        for (int i = 0; i < mejor.getSolicitud().size(); i++) {
            if (Integer.parseInt(mejor.getSolicitud().get(i).toString()) == 1) {
                for (int e = 0; e < vError.size(); e++) {
                    if (infoSolicitudes.get(i).getNumeroGrupo() == Integer.parseInt(vError.get(e).get("idGrupo").toString())) {
                        errorGrupo.addElement(new ErrorGrupo(infoSolicitudes.get(i).getIdAsignatura(), infoSolicitudes.get(i).getNumeroGrupo(), 1));
                    }
                }
            }
        }
        //devuelve los grupos a los que se le tiene que hacer huecos
        return errorGrupo;
    }

    /**
     * Se encarga de realizar el post-Algoritmo para hacer hueco a cada uno de
     * los grupos de errorGrupo
     *
     * @param errorGrupo: Vector de grupos a los que hacer hueco
     *
     * @return devuelve un numero con el numero de cambios realizados
     */
    public int postAlgoritmo(Vector<ErrorGrupo> errorGrupo) {
        //Declaración de variables
        Arbol arbol = new Arbol();
        int cont = 0;
        int aux = 0;
        int numAsig = 0;
        Nodo raiz = null;
        Nodo mejor = null;
        Vector copiaSolicitudes = null;
        Vector<Solicitud> infoSolicitudes = null;
        Vector solicitudes = new Vector();
        boolean hueco = false;
        Vector<Hashtable> hashAlumnoHueco = null;
        //Realiza el post-Algoritmo por cada uno de los elementos de errorGrupo
        for (int i = 0; i < errorGrupo.size(); i++) {
            //Lista los alumnos que tienen como grupo aprobado el grupo al que hacer hueco  
            hashAlumnoHueco = listarAlumnosHueco(errorGrupo.get(i).getNumeroGrupo());
            while (aux < hashAlumnoHueco.size() && hueco == false) {
                //Reducir numero de plazas ocupadas de 
                System.out.println("AlumnoError " + Integer.parseInt(hashAlumnoHueco.get(aux).get("idAlumno").toString()));
                reducirPlazasOcupadas(Integer.parseInt(hashAlumnoHueco.get(aux).get("idAlumno").toString()));
                //Lista todos los grupos de las asignaturas que ha solicitado el alumno, menos el grupo al que hacerle los huecos
                System.out.println("Reduccida");
                infoSolicitudes = listarGruposHueco(Integer.parseInt(hashAlumnoHueco.get(aux).get("idAlumno").toString()), errorGrupo.get(i).getNumeroGrupo());
                if (!infoSolicitudes.isEmpty()) {
                    //Se crea el arbol 
                    solicitudes = new Vector();
                    for (int e = 0; e < infoSolicitudes.size(); e++) {
                        System.out.println("POSTALGORITMO>NumeroGrupo:" + infoSolicitudes.get(e).getNumeroGrupo() + " prioridad: " + infoSolicitudes.get(e).getPrioridad() + " Asignatura: " + infoSolicitudes.get(e).getIdAsignatura() + " Horario: " + infoSolicitudes.get(e).vHorarioToString());
                        solicitudes.addElement(0);
                    }
                    System.out.println("contarAsignaturasSolicitudas");
                    numAsig = contarAsignaturasSolicitadas(Integer.parseInt(hashAlumnoHueco.get(aux).get("idAlumno").toString()));
                    System.out.println("se hace el arbol");
                    raiz = new Nodo(valorarSolicitud(solicitudes, numAsig, infoSolicitudes), solicitudes);
                    copiaSolicitudes = new Vector();
                    for (int e = 0; e < solicitudes.size(); e++) {
                        copiaSolicitudes.addElement(0);
                    }
                    copiaSolicitudes.set(0, 1);
                    mejor = arbol.rellenarArbol(copiaSolicitudes, 0, null, numAsig, numAsig, infoSolicitudes, raiz, raiz);
                    //Si el valor del mejor nodo es igual o mayor al numero de asignaturas, entonces se ha conseguido hacer un hueco
                    if (mejor.getValor() >= numAsig) {
                        hueco = true;
                        cont++;
                        System.out.println("HUECO numeroASig= " + numAsig + " valor del mejor nodo -> " + mejor.getValor() + " solicitudes -> " + mejor.getStringSolicitud());
                        anadirSolicitudHueco(infoSolicitudes, mejor.getSolicitud(), Integer.parseInt(hashAlumnoHueco.get(aux).get("idAlumno").toString()));
                        //Si el valor del mejor nodo es menor al numero de asignaturas, entonces no se ha conseguido hacer el hueco y hay que restaurar el numero de plazas
                    } else {
                        System.out.print("NO HUECO numeroASig= " + numAsig + " valor del mejor nodo -> " + mejor.getValor() + " solicitudes -> " + mejor.getStringSolicitud());
                        aumentarPlazasOcupadas(Integer.parseInt(hashAlumnoHueco.get(aux).get("idAlumno").toString()));
                        System.out.println(" AUMENTADA ANTERIO");
                    }
                }
                aux++;
            }
            hueco = false;
            // algoritmo.aumentarPlazasOcupadas(Integer.parseInt(hashAlumno.get(i).get("idAlumno").toString()));
        }
        return cont;
    }

    /**
     * valida la solictud y devuelve true la solictud es posible.
     *
     * @param solicitudes: un vector que contiene 1 ò 0 dependiendo de si dicho
     * grupo esta dentro del horario o no
     * @param posicion: elemento que se quiere modificar
     * @param infoSolicitudes: vector con toda la información necesaria sobre
     * las solicitudes
     *
     * @return true si solicitud es conpatible
     */
    public boolean validarSolicitud(Vector solicitudes, int posicion, Vector<Solicitud> infoSolicitudes) {
        boolean validar = true;
        for (int i = 0; i < solicitudes.size(); i++) {
            if (Integer.parseInt(solicitudes.get(i).toString()) == 1) {
                if (infoSolicitudes.get(i).getIdAsignatura() == infoSolicitudes.get(posicion).getIdAsignatura()) {
                    return false;
                } else {
                    for (int e = 0; e < infoSolicitudes.get(posicion).getVHorario().size(); e++) {
                        for (int a = 0; a < infoSolicitudes.get(i).getVHorario().size(); a++) {
                            if (infoSolicitudes.get(posicion).getVHorario().get(e).getDuracion() > 1) {
                                if (infoSolicitudes.get(posicion).getVHorario().get(e).getDuracion() == 2) {
                                    if ((infoSolicitudes.get(posicion).getVHorario().get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && infoSolicitudes.get(posicion).getVHorario().get(e).getIdHora() == infoSolicitudes.get(i).getVHorario().get(a).getIdHora()) || (infoSolicitudes.get(posicion).getVHorario().get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && infoSolicitudes.get(posicion).getVHorario().get(e).getIdHora() + 1 == infoSolicitudes.get(i).getVHorario().get(a).getIdHora())) {
                                        return false;
                                    }
                                } else {
                                    if ((infoSolicitudes.get(posicion).getVHorario().get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && infoSolicitudes.get(posicion).getVHorario().get(e).getIdHora() == infoSolicitudes.get(i).getVHorario().get(a).getIdHora()) || (infoSolicitudes.get(posicion).getVHorario().get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && infoSolicitudes.get(posicion).getVHorario().get(e).getIdHora() + 1 == infoSolicitudes.get(i).getVHorario().get(a).getIdHora()) || (infoSolicitudes.get(posicion).getVHorario().get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && infoSolicitudes.get(posicion).getVHorario().get(e).getIdHora() + 2 == infoSolicitudes.get(i).getVHorario().get(a).getIdHora())) {
                                        return false;
                                    }
                                }
                                if (infoSolicitudes.get(i).getVHorario().get(e).getDuracion() > 1) {
                                    if (infoSolicitudes.get(i).getVHorario().get(e).getDuracion() == 2) {
                                        if ((infoSolicitudes.get(posicion).getVHorario().get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && infoSolicitudes.get(posicion).getVHorario().get(e).getIdHora() == infoSolicitudes.get(i).getVHorario().get(a).getIdHora()) || (infoSolicitudes.get(posicion).getVHorario().get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && infoSolicitudes.get(posicion).getVHorario().get(e).getIdHora() == infoSolicitudes.get(i).getVHorario().get(a).getIdHora() + 1)) {
                                            return false;
                                        }
                                    } else {
                                        if ((infoSolicitudes.get(posicion).getVHorario().get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && infoSolicitudes.get(posicion).getVHorario().get(e).getIdHora() == infoSolicitudes.get(i).getVHorario().get(a).getIdHora()) || (infoSolicitudes.get(posicion).getVHorario().get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && infoSolicitudes.get(posicion).getVHorario().get(e).getIdHora() == infoSolicitudes.get(i).getVHorario().get(a).getIdHora() + 1) || (infoSolicitudes.get(posicion).getVHorario().get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && infoSolicitudes.get(posicion).getVHorario().get(e).getIdHora() == infoSolicitudes.get(i).getVHorario().get(a).getIdHora() + 2)) {
                                            return false;
                                        }
                                    }
                                }
                            } else {
                                if (infoSolicitudes.get(i).getVHorario().get(e).getDuracion() > 1) {
                                    if (infoSolicitudes.get(i).getVHorario().get(e).getDuracion() == 2) {
                                        if ((infoSolicitudes.get(posicion).getVHorario().get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && infoSolicitudes.get(posicion).getVHorario().get(e).getIdHora() == infoSolicitudes.get(i).getVHorario().get(a).getIdHora()) || (infoSolicitudes.get(posicion).getVHorario().get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && infoSolicitudes.get(posicion).getVHorario().get(e).getIdHora() == infoSolicitudes.get(i).getVHorario().get(a).getIdHora() + 1)) {
                                            return false;
                                        }
                                    } else {
                                        if ((infoSolicitudes.get(posicion).getVHorario().get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && infoSolicitudes.get(posicion).getVHorario().get(e).getIdHora() == infoSolicitudes.get(i).getVHorario().get(a).getIdHora()) || (infoSolicitudes.get(posicion).getVHorario().get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && infoSolicitudes.get(posicion).getVHorario().get(e).getIdHora() == infoSolicitudes.get(i).getVHorario().get(a).getIdHora() + 1) || (infoSolicitudes.get(posicion).getVHorario().get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && infoSolicitudes.get(posicion).getVHorario().get(e).getIdHora() == infoSolicitudes.get(i).getVHorario().get(a).getIdHora() + 2)) {
                                            return false;
                                        }
                                    }
                                } else {
                                    if (infoSolicitudes.get(posicion).getVHorario().get(e).getIdHorario() == infoSolicitudes.get(i).getVHorario().get(a).getIdHorario()) {
                                        return false;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return validar;
    }

    /**
     * Añade el numero de grupos sobre una asignatura
     *
     * @param infoSolicitud: identificador de la asignatura
     * @param solicitud: numero de grupos a insertar
     * @param idAlumno: identificador de alumno
     * @return número de elementos añadidos a la base de datos
     */
    public int anadirSolicitudAprobada(Vector<Solicitud> infoSolicitud, Vector solicitud, int idAlumno) {
        int iresultado = 0;
        try {
            iresultado = dGenerarHorarios.eliminarSolicitudesAprobadas(idAlumno);
            //Se realiza la inserción en la base de datos
            for (int i = 0; i < solicitud.size(); i++) {
                if (Integer.parseInt(solicitud.get(i).toString()) == 1) {

                    iresultado = dGenerarHorarios.anadirSolicitudAprobada(infoSolicitud.get(i).getNumeroGrupo(), idAlumno);
                }
            }
        } catch (Exception e) {
        }
        return iresultado;
    }

    /**
     * Añade la petición de un cambio de grupo
     *
     * @param idAlumno: identificador de alumno
     * @param grupoAntiguo: identificador del grupo antiguo
     * @param grupoNuevo: identificador del grupo nuevo
     *
     * @return número de elementos añadidos a la base de datos
     */
    public int anadirCambioGrupo(int idAlumno, int grupoAntiguo, int grupoNuevo) {
        int iresultado = 0;
        try {
            System.out.println("añadir al cambio grupo");
            //Se añade la solicitud de cambio de grupo
            iresultado = dGenerarHorarios.anadirCambioGrupo(idAlumno, grupoAntiguo, grupoNuevo);
        } catch (Exception e) {
        }
        return iresultado;
    }

    /**
     * Añade el numero de grupos sobre una asignatura
     *
     * @param infoSolicitud: identificador de la asignatura
     * @param solicitud: numero de grupos a insertar
     * @param idAlumno: identificador de alumno
     *
     * @return número de elementos añadidos a la base de datos
     */
    public int anadirSolicitudHueco(Vector<Solicitud> infoSolicitud, Vector solicitud, int idAlumno) {
        int iresultado = 0;
        try {
            iresultado = dGenerarHorarios.eliminarSolicitudesHueco(idAlumno);
            //Se realiza la inserción en la base de datos
            for (int i = 0; i < solicitud.size(); i++) {
                if (Integer.parseInt(solicitud.get(i).toString()) == 1) {

                    iresultado = dGenerarHorarios.anadirSolicitudHueco(infoSolicitud.get(i).getNumeroGrupo(), idAlumno);
                }
            }
            //Aumenta el numero de plazas ocupadas de los grupos insertados
            dGenerarHorarios.aumentarPlazasOcupadasHueco(idAlumno);
        } catch (Exception e) {
        }
        return iresultado;
    }

    /**
     * Se inserta la solicitud de grupo de un alumno
     *
     * @param idAlumno: identificador de alumno
     * @param idGrupo: identificador de grupo
     *
     * @return número de elementos añadidos a la base de datos
     */
    public int insertarSolicitud(int idAlumno, int idGrupo) {
        int resultado = 0;
        //Se añade la solicitud de grupo
        resultado = dGenerarHorarios.anadirSolicitudAprobada(idGrupo, idAlumno);
        return resultado;
    }

    /**
     * Se elimina la solicitud de cambio de grupo de un alumno
     *
     * @param idAlumno: identificador de alumno
     * @param idGrupoAntiguo: identificador del grupo antiguo
     * @param idGrupoNuevo: identificador del grupo nuevo
     *
     * @return número de elementos eliminados de la base de datos
     */
    public int eliminarCambioGrupo(int idAlumno, int idGrupoAntiguo, int idGrupoNuevo) {
        int resultado = 0;
        //Se elimina el cambio de grupo
        resultado = dGenerarHorarios.eliminarCambioGrupo(idGrupoAntiguo, idGrupoNuevo, idAlumno);
        return resultado;
    }

    /**
     * Se elimina todas las solicitudes de cambio de grupo de un alumno
     *
     * @param idAlumno: identificador de alumno
     *
     * @return número de elementos eliminados de la base de datos
     */
    public int eliminarCambioGrupo(int idAlumno) {
        int resultado = 0;
        //Se elimina todos los cambios de grupos de un alumno
        resultado = dGenerarHorarios.eliminarCambioGrupo(idAlumno);
        return resultado;
    }

    /**
     * Restaura todas las solicitudes provisionales del post-Algoritmo
     *
     * @return no devuelve nada
     */
    public void restaurarProvisionales() {
        //Lista los alumnos que estan involucrados en el cambio
        Vector v = dGenerarHorarios.listarAlumnosProvisionales();
        for (int i = 0; i < v.size(); i++) {
            //Elimina las solicitudes de los alumnos
            dGenerarHorarios.eliminarSolicitudesAprobadas(Integer.parseInt(((Hashtable) v.get(i)).get("idAlumno").toString()));
            //dAlgoritmo.eliminarTodosCambioGrupo(Integer.parseInt(((Hashtable) v.get(i)).get("idAlumno").toString()));
        }
        //Pasar las solicitudHueco a la tabla solicitudaprobadas
        dGenerarHorarios.restaurarProvisionales();
        //Elimina todas las solicitudes de la tabla solicitudHueco
        dGenerarHorarios.eliminarTodasSolicitudesHueco();
    }

    /**
     * se encarga de buscar un cambio de grupo
     *
     * @param nombreUsuario: nombre de Usuario
     * @param idGrupoAntiguo: identificador del grupo antiguo
     * @param idGrupoNuevo: identificador del grupo nuevo
     *
     * @return Un vector con la información del grupo nuevo
     */
    public Vector SeleccionarGrupoNuevo(int idGrupoNuevo, int idGrupoAntiguo, int nombreUsuario) {
        Vector resultado = null;
        resultado = dGenerarHorarios.SeleccionarGrupoNuevo(idGrupoNuevo, idGrupoAntiguo, nombreUsuario);
        return resultado;
    }

    /**
     * se encarga de buscar un cambio de grupo
     *
     * @param nombreUsuario: nombre de Usuario
     * @param idGrupoAntiguo: identificador del grupo antiguo
     * @param idGrupoNuevo: identificador del grupo nuevo
     *
     * @return Un vector con la información del grupo nuevo
     */
    public int restaurarAprobadas() {
        int resultado = 0;
        Vector v = dGenerarHorarios.listarAlumnosProvisionales();
        for (int i = 0; i < v.size(); i++) {
            dGenerarHorarios.reducirPlazasOcupadasHueco(Integer.parseInt(((Hashtable) v.get(i)).get("idAlumno").toString()));
//            dAlgoritmo.aumentarPlazasOcupadasHueco(Integer.parseInt(((Hashtable) v.get(i)).get("idAlumno").toString()));
            dGenerarHorarios.aumentarPlazasOcupadas(Integer.parseInt(((Hashtable) v.get(i)).get("idAlumno").toString()));
        }
        dGenerarHorarios.eliminarTodasSolicitudesHueco();
        return resultado;
    }

    public int reducirPlazasOcupadas(int idAlumno) {
        int resultado = 0;
        resultado = dGenerarHorarios.reducirPlazasOcupadas(idAlumno);
        return resultado;
    }

    public int reducirPlazasOcupadasIdGrupo(int idGrupo) {
        int resultado = 0;
        resultado = dGenerarHorarios.reducirPlazasOcupadasIdGrupo(idGrupo);
        return resultado;
    }

    public int aumentarPlazasOcupadas(int idAlumno) {
        int resultado = 0;
        resultado = dGenerarHorarios.aumentarPlazasOcupadas(idAlumno);
        return resultado;
    }

    public int aumentarPlazasOcupadasIdGrupo(int idGrupo) {
        int resultado = 0;
        resultado = dGenerarHorarios.aumentarPlazasOcupadasIdGrupo(idGrupo);
        return resultado;
    }

    /**
     * selecciona las asignaturas no asignadas.
     *
     * @param idAlumno: identificador del alumno
     *
     * @return Vector con las asignaturas no asignadas.
     */
    public Vector<Hashtable> seleccionarErroresGrupo(int idAlumno) {
        Vector<Hashtable> hashResultado = new Vector();
        //Se busca en la base de datos todas las asignaturas solicitadas no aprobadas
        hashResultado = (Vector<Hashtable>) dGenerarHorarios.seleccionarErroresGrupo(idAlumno);
        return hashResultado;
    }

    /**
     * Lista todo el horario de un grupo
     *
     * @param idGrupo: identificador del grupo
     *
     * @return devuelve un vector con todos los horarios de un grupo
     */
    public Vector<HorarioSolicitud> ListarHorario(int idGrupo) {
        //Declaración de variables
        Vector vResultado = null;
        Vector<HorarioSolicitud> vHorario = new Vector();
        //Buscar los horarios de un grupo
        vResultado = dGenerarHorarios.seleccionarHorarios(idGrupo);

        for (int i = 0; i < vResultado.size(); i++) {
            vHorario.addElement(new HorarioSolicitud(Integer.parseInt(((Hashtable) vResultado.get(i)).get("idHorario").toString()), Integer.parseInt(((Hashtable) vResultado.get(i)).get("idDia").toString()), Integer.parseInt(((Hashtable) vResultado.get(i)).get("idHora").toString()), Integer.parseInt(((Hashtable) vResultado.get(i)).get("duracion").toString())));
        }
        return vHorario;
    }

    /**
     * Elimina las solicitudes aprobadas de un alumno
     *
     * @param idAlumno: identificador del alumno
     *
     * @return devuelve el numero de elementos eliminados
     */
    public int eliminarSolicitudesAprobadas(int idAlumno) {
        int resultado = 0;
        resultado = dGenerarHorarios.eliminarSolicitudesAprobadas(idAlumno);
        return resultado;
    }

    /**
     * Elimina las solicitudes aprobadas de un alumno
     *
     * @param idAlumno: identificador del alumno
     *
     * @return devuelve el numero de elementos eliminados
     */
    public int eliminarSolicitudesAprobadas(int idAlumno, int idGrupo) {
        int resultado = 0;
        resultado = dGenerarHorarios.eliminarSolicitudesAprobadas(idAlumno, idGrupo);
        return resultado;
    }

    /**
     * Cuenta el numero de asignaturas que un alumno ha solicitado
     *
     * @param idAlumno: identificador del alumno
     *
     * @return devuelve el numero de asignaturas solicitadas por un alumnos
     */
    public int contarAsignaturasSolicitadas(int idAlumno) {
        Vector v = null;
        int resultado = 0;
        v = dGenerarHorarios.contarAsignaturasSolicitadas(idAlumno);
        resultado = v.size();
        return resultado;
    }

    /**
     * Se encarga de validad una solicitud
     *
     * @param idAlumno: identificador del alumno
     *
     * @return devuelve el numero de asignaturas solicitadas por un alumnos
     */
    public int validarSolicitudGrupo(Vector<HorarioSolicitud> horarioSolicitud, Vector<SolicitudGrupo> infoSolicitudes) {
        int validar = -1;
        for (int i = 0; i < infoSolicitudes.size(); i++) {
            for (int e = 0; e < horarioSolicitud.size(); e++) {
                for (int a = 0; a < infoSolicitudes.get(i).getVHorario().size(); a++) {
                    if (horarioSolicitud.get(e).getDuracion() > 1) {
                        if (horarioSolicitud.get(e).getDuracion() == 2) {
                            if ((horarioSolicitud.get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && horarioSolicitud.get(e).getIdHora() == infoSolicitudes.get(i).getVHorario().get(a).getIdHora()) || (horarioSolicitud.get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && horarioSolicitud.get(e).getIdHora() + 1 == infoSolicitudes.get(i).getVHorario().get(a).getIdHora())) {
                                return i;
                            }
                        } else {
                            if ((horarioSolicitud.get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && horarioSolicitud.get(e).getIdHora() == infoSolicitudes.get(i).getVHorario().get(a).getIdHora()) || (horarioSolicitud.get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && horarioSolicitud.get(e).getIdHora() + 1 == infoSolicitudes.get(i).getVHorario().get(a).getIdHora()) || (horarioSolicitud.get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && horarioSolicitud.get(e).getIdHora() + 2 == infoSolicitudes.get(i).getVHorario().get(a).getIdHora())) {
                                return i;
                            }
                        }
                        if (infoSolicitudes.get(i).getVHorario().get(e).getDuracion() > 1) {
                            if (infoSolicitudes.get(i).getVHorario().get(e).getDuracion() == 2) {
                                if ((horarioSolicitud.get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && horarioSolicitud.get(e).getIdHora() == infoSolicitudes.get(i).getVHorario().get(a).getIdHora()) || (horarioSolicitud.get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && horarioSolicitud.get(e).getIdHora() == infoSolicitudes.get(i).getVHorario().get(a).getIdHora() + 1)) {
                                    return i;
                                }
                            } else {
                                if ((horarioSolicitud.get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && horarioSolicitud.get(e).getIdHora() == infoSolicitudes.get(i).getVHorario().get(a).getIdHora()) || (horarioSolicitud.get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && horarioSolicitud.get(e).getIdHora() == infoSolicitudes.get(i).getVHorario().get(a).getIdHora() + 1) || (horarioSolicitud.get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && horarioSolicitud.get(e).getIdHora() == infoSolicitudes.get(i).getVHorario().get(a).getIdHora() + 2)) {
                                    return i;
                                }
                            }
                        }
                    } else {
                        if (infoSolicitudes.get(i).getVHorario().get(e).getDuracion() > 1) {
                            if (infoSolicitudes.get(i).getVHorario().get(e).getDuracion() == 2) {
                                if ((horarioSolicitud.get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && horarioSolicitud.get(e).getIdHora() == infoSolicitudes.get(i).getVHorario().get(a).getIdHora()) || (horarioSolicitud.get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && horarioSolicitud.get(e).getIdHora() == infoSolicitudes.get(i).getVHorario().get(a).getIdHora() + 1)) {
                                    return i;
                                }
                            } else {
                                if ((horarioSolicitud.get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && horarioSolicitud.get(e).getIdHora() == infoSolicitudes.get(i).getVHorario().get(a).getIdHora()) || (horarioSolicitud.get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && horarioSolicitud.get(e).getIdHora() == infoSolicitudes.get(i).getVHorario().get(a).getIdHora() + 1) || (horarioSolicitud.get(e).getIdDia() == infoSolicitudes.get(i).getVHorario().get(a).getIdDia() && horarioSolicitud.get(e).getIdHora() == infoSolicitudes.get(i).getVHorario().get(a).getIdHora() + 2)) {
                                    return i;
                                }
                            }
                        } else {
                            if (horarioSolicitud.get(e).getIdHorario() == infoSolicitudes.get(i).getVHorario().get(a).getIdHorario()) {
                                return i;
                            }
                        }
                    }
                }
            }
        }
        return validar;
    }

    public int sumarSolicitudesMaxPrioridad(int idAlumno) {
        Vector<Hashtable> h = null;
        Vector<Hashtable> hLibre = null;
        Vector<SolicitudGrupo> vSolicitudGrupo = new Vector();
        Vector<HorarioSolicitud> vHorarioSolicitud = new Vector();
        int resultado = 0;
        int indice = 0;
        int numGrupSol = 0;
        h = (Vector<Hashtable>) dGenerarHorarios.mostarSolicitudesMaxPrioridad(idAlumno);
        for (int i = 0; i < h.size(); i++) {
            vHorarioSolicitud = ListarHorario(Integer.parseInt(h.get(i).get("idGrupo").toString()));
            indice = validarSolicitudGrupo(vHorarioSolicitud, vSolicitudGrupo);
            if (indice == -1) {
                if (Integer.parseInt(h.get(i).get("prioridad").toString()) == 1) {
                    resultado += 15;
                } else {
                    if (Integer.parseInt(h.get(i).get("prioridad").toString()) == 2) {
                        resultado += 10;
                    } else {
                        resultado += 5;
                    }
                }
                vSolicitudGrupo.addElement(new SolicitudGrupo(Integer.parseInt(h.get(i).get("idGrupo").toString()), Integer.parseInt(h.get(i).get("prioridad").toString()), ListarHorario(Integer.parseInt(h.get(i).get("idGrupo").toString()))));

            } else {
                numGrupSol++;
                resultado++;
                if (vSolicitudGrupo.get(indice).getPrioridad() > Integer.parseInt(h.get(i).get("prioridad").toString())) {
                    if (vSolicitudGrupo.get(indice).getPrioridad() == 1) {
                        resultado -= 15;
                    } else {
                        if (vSolicitudGrupo.get(indice).getPrioridad() == 2) {
                            resultado -= 10;
                        } else {
                            resultado -= 5;
                        }
                    }
                    vSolicitudGrupo.remove(indice);
                    if (Integer.parseInt(h.get(i).get("prioridad").toString()) == 1) {
                        resultado += 15;
                    } else {
                        if (Integer.parseInt(h.get(i).get("prioridad").toString()) == 2) {
                            resultado += 10;
                        } else {
                            resultado += 5;
                        }
                    }
                    vSolicitudGrupo.addElement(new SolicitudGrupo(Integer.parseInt(h.get(i).get("idGrupo").toString()), Integer.parseInt(h.get(i).get("prioridad").toString()), ListarHorario(Integer.parseInt(h.get(i).get("idGrupo").toString()))));
                }
            }
        }

        hLibre = (Vector<Hashtable>) dGenerarHorarios.mostarSolicitudesMaxPrioridadConPlazas(idAlumno);
        if (h.size() != hLibre.size()) {
            System.out.println("HAY ASIGNATURAS COMPLETAS");
            resultado = 0;
            indice = 0;
            vSolicitudGrupo = new Vector();
            for (int i = 0; i < hLibre.size(); i++) {
                vHorarioSolicitud = ListarHorario(Integer.parseInt(hLibre.get(i).get("idGrupo").toString()));
                indice = validarSolicitudGrupo(vHorarioSolicitud, vSolicitudGrupo);
                if (indice == -1) {
                    if (Integer.parseInt(hLibre.get(i).get("prioridad").toString()) == 1) {
                        resultado += 15;
                    } else {
                        if (Integer.parseInt(hLibre.get(i).get("prioridad").toString()) == 2) {
                            resultado += 10;
                        } else {
                            resultado += 5;
                        }
                    }
                    vSolicitudGrupo.addElement(new SolicitudGrupo(Integer.parseInt(hLibre.get(i).get("idGrupo").toString()), Integer.parseInt(hLibre.get(i).get("prioridad").toString()), ListarHorario(Integer.parseInt(hLibre.get(i).get("idGrupo").toString()))));
                } else {
                    numGrupSol++;
                    resultado++;
                    if (vSolicitudGrupo.get(indice).getPrioridad() > Integer.parseInt(hLibre.get(i).get("prioridad").toString())) {
                        if (vSolicitudGrupo.get(indice).getPrioridad() == 1) {
                            resultado -= 15;
                        } else {
                            if (vSolicitudGrupo.get(indice).getPrioridad() == 2) {
                                resultado -= 10;
                            } else {
                                resultado -= 5;
                            }
                        }
                        vSolicitudGrupo.remove(indice);
                        if (Integer.parseInt(hLibre.get(i).get("prioridad").toString()) == 1) {
                            resultado += 15;
                        } else {
                            if (Integer.parseInt(hLibre.get(i).get("prioridad").toString()) == 2) {
                                resultado += 10;
                            } else {
                                resultado += 5;
                            }
                        }
                        vSolicitudGrupo.addElement(new SolicitudGrupo(Integer.parseInt(hLibre.get(i).get("idGrupo").toString()), Integer.parseInt(hLibre.get(i).get("prioridad").toString()), ListarHorario(Integer.parseInt(hLibre.get(i).get("idGrupo").toString()))));
                    }
                }
            }

            resultado = resultado + (h.size() - hLibre.size());
        }
        System.out.println("RESULTADO DE VALOR MAX = " + resultado);
        return resultado;
    }

    /**
     * Lista los alumnos que estan en la tabla solicitudHueco
     *
     * @param idGrupo: identificador del grupo
     *
     * @return listado de alumnos
     */
    public Vector<Hashtable> listarAlumnosHueco(int idGrupo) {
        Vector<Hashtable> hashAlumno = new Vector();
        Vector v = new Vector();
        v = dGenerarHorarios.listarAlumnoHueco(idGrupo);
        hashAlumno = (Vector<Hashtable>) v;
        return hashAlumno;
    }

    /**
     * Listado de grupos de un alumno de la tabla solicitudHueco
     *
     * @param idAlumno: identificador del alumno
     * @param idGrupo: identificador del grupo
     *
     * @return listados de los grupos menos idGrupo
     */
    public Vector<Solicitud> listarGruposHueco(int idAlumno, int idGrupo) {
        //Declaración de variables
        Vector<Hashtable> hashResultado = new Vector();
        Vector<Solicitud> infoSolicitudes = new Vector();
        hashResultado = (Vector<Hashtable>) dGenerarHorarios.seleccionarGruposHueco(idGrupo, idAlumno);
        
        for (int i = 0; i < hashResultado.size(); i++) {
            infoSolicitudes.addElement(new Solicitud(Integer.parseInt(hashResultado.get(i).get("idGrupo").toString()), Integer.parseInt(hashResultado.get(i).get("idAsignatura").toString())));
            infoSolicitudes.get(i).setVHorario(ListarHorario(infoSolicitudes.get(i).getNumeroGrupo()));
        }

        return infoSolicitudes;
    }

    /**
     * Se encarga de enviar correos a los alumnos a los que se le ha asignado el
     * horario
     *
     * @return No devuelve nada
     */
    public void enviarCorreos() {
        //Declaracion de variables
        try {
            String path = GestorRutas.getInstance().getWebInfPath();
            GestorEmail gestorEmail = new GestorEmail(path, "DatosAplicacion.properties");
            Vector<Hashtable> vAlumno = new Vector();
            String asunto = "";
            String cuerpo = "";

            //listar correo de los alumnos a los que se le ha asignado grupos
            vAlumno = (Vector<Hashtable>) dGenerarHorarios.listarAlumnosAprobados();
            asunto = "gestHora: Asignación de horario";
            cuerpo = "Recibe este correo debido a que se le ha asignado un horario. \n\nPuede consultar su horario desde su cuenta. \n\n";

            //Enviar correo a los alumnos para comunicarle que ya se le ha asignado horarios
            for (int i = 0; i < vAlumno.size(); i++) {
                gestorEmail.enviarEmail(vAlumno.get(i).get("email").toString(), asunto, cuerpo);
            }
        } catch (Exception e) {
        }
    }
}
